package com.bjy.qa.service.functionaltest.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bjy.qa.dao.functionaltest.AgentDao;
import com.bjy.qa.entity.MyPage;
import com.bjy.qa.entity.ResponsePagingData;
import com.bjy.qa.entity.functionaltest.Agent;
import com.bjy.qa.entity.user.User;
import com.bjy.qa.enumtype.AgentStatus;
import com.bjy.qa.exception.MyException;
import com.bjy.qa.service.functionaltest.IAgentService;
import com.bjy.qa.util.mqtt.MqttLaunchTool;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class AgentService implements IAgentService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${qa-platform.mqtt.url}")
    private String mqttUrl;

    @Value("${qa-platform.mqtt.base-topic}")
    private String mqttBaseTopic;

    @Value("${qa-platform.mqtt.qos}")
    private String mqttQos;

    @Value("${qa-platform.mqtt.allow-anonymous:false}")
    private Boolean mqttAllowAnonymous;

    @Value("${qa-platform.mqtt.username}")
    private String mqttUserName;

    @Value("${qa-platform.mqtt.password}")
    private String mqttPassword;

    @Value("${qa-platform.secret-key}")
    String secretKey;

    @Resource
    AgentDao agentDao;

    @Override
    public Map<String, Object> agentSignOn(Agent parAgent) {
        QueryWrapper<Agent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("`key`", parAgent.getKey());
        Agent agent = agentDao.selectOne(queryWrapper); // 查找 agent 信息
        if (agent == null) {
            throw new MyException("agent key 验证失败!");
        }

        agent.setVersion(parAgent.getVersion());
        agent.setSystemType(parAgent.getSystemType());
        agent.setAddress(parAgent.getAddress());
        agent.setMockBaseUrl(parAgent.getMockBaseUrl());
        agentDao.updateById(agent);

        // 构造 mqtt 返回信息
        Map<String, Object> mqtt = new HashMap<>();
        mqtt.put("url", mqttUrl);
        mqtt.put("baseTopic", mqttBaseTopic);
        mqtt.put("qos", mqttQos);
        mqtt.put("allowAnonymous", mqttAllowAnonymous);
        mqtt.put("userName", mqttUserName);
        mqtt.put("password", mqttPassword);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("mqtt", mqtt);

        resultMap.put("secretKey", secretKey); // 添加 secretKey

        // 生成 token agent 的 account = AGENT_TOKEN， 校验的时候会跳过 account = AGENT_TOKEN 的
        User user = new User();
        user.setId(agent.getId());
        user.setAccount("AGENT_TOKEN");
        user.setCode(agent.getKey());
        return resultMap;
    }

    @Override
    public List<Agent> listAll() {
        return agentDao.selectList(new QueryWrapper<>());
    }

    @Override
    public ResponsePagingData list(MyPage<Agent> myPage) {
        Page<Agent> page = new Page(myPage.getPageNum(), myPage.getPageSize()); // 创建一个 Page 对象，用于进行分页查询
        page.setOrders(myPage.getOrders()); // 设置排序规则

        // 构造待查询 QueryWrapper
        Agent agent = myPage.getQuery();
        QueryWrapper<Agent> queryWrapper = new QueryWrapper<>();

        // 检查 Agent 是否为空
        if (agent != null) {
            // 如果 Agent 不为空，并且其名称不为空或长度不为0，则模糊查询名称
            if (StringUtils.isNotBlank(agent.getName())) {
                queryWrapper.like("name", agent.getName());
            }
        }

        page = agentDao.selectPage(page, queryWrapper); // 按分页查询
        myPage.setTotalRecords(page.getTotal()); // 设置返回总记录数

        return new ResponsePagingData(myPage, page.getRecords());
    }

    @Override
    public Object add(Agent agent) {
        UUID uuid = UUID.randomUUID();// 创建 UUID 的对象
        agent.setKey(uuid.toString());// 将 UUID 转化为字符串，并设置为 Agent 的 Key
        agent.setStatus(AgentStatus.OFF_LINE.getValue());

        return agentDao.insert(agent);// 将 Agent 插入到库中
    }

    @Override
    public int update(Agent agent) {
        agent.setCreatedAt(null); // 清除时间戳，让数据库自动处理
        agent.setUpdatedAt(null); // 清除时间戳，让数据库自动处理

        return agentDao.updateById(agent);
    }

    @Override
    public Object reboot(String key) {
        String msg = "{ \"msg\": \"reboot\" }";
        this.pubCmd(key, "reboot", msg);
        return true;
    }

    @Override
    public Agent getOnlineAgent() {
        QueryWrapper<Agent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", AgentStatus.ON_LINE.getValue());
        queryWrapper.last("LIMIT 1");
        return agentDao.selectOne(queryWrapper);
    }

    public boolean pubCmd(String agentKey, String cmdStr, String msg) {
        String downTopic = mqttBaseTopic + "/DOWN/" + agentKey;

        logger.info("--> topic: {}", downTopic);
        logger.info("--> message: {}", msg);

        MqttLaunchTool.pubCmd(agentKey, downTopic, msg);

        logger.info(cmdStr + " 发送成功。topic:{}: ", downTopic);
        return true;
    }
}
